﻿using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using HistogramControlTest.Interfaces;

namespace HistogramControlTest.Controls
{
    /// <summary>
    /// 柱状图控件组
    /// </summary>
    public class HistogramGroup : Control, IHistogramGroup
    {
        #region 字段
        private bool _isShowText;
        private double _topGridWidth;
        private double _topGridHeight;

        private Grid _topGrid;
        private StackPanel _innertPanel;
        private ScrollViewer _scrollViewer;

        private Storyboard _activateHisStoryboard;
        private DoubleAnimation _animation1, _animation2;

        /// <summary>
        /// 缓存面板
        /// </summary>
        private readonly StackPanel _cacheStackPanel = new StackPanel();
        /// <summary>
        /// 显示状态柱状图控件集合
        /// </summary>
        private readonly List<HistogramControl> _displayHistogramList = new List<HistogramControl>();
        /// <summary>
        /// 柱状图控件集合
        /// </summary>
        private readonly List<HistogramControl> _histogramControlList = new List<HistogramControl>();
        #endregion

        #region 属性
        /// <summary>
        /// 控件组实际高度
        /// </summary>
        public double FactHeight { get; set; }

        /// <summary>
        /// 是否显示底部文字
        /// </summary>
        public bool IsShowText
        {
            get { return _isShowText; }
            set
            {
                _isShowText = value;
                TextVisible = value ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        /// <summary>
        /// 是否可以操作
        /// </summary>
        public bool IsOperable { get; set; }

        /// <summary>
        /// 当前激活的柱状图控件
        /// </summary>
        public HistogramControl ActivateHistogram { get; private set; }

        /// <summary>
        /// 当前选中的柱状图控件
        /// </summary>
        public HistogramControl CheckedHistogram { get; private set; }
        #endregion

        #region 依赖属性
        /// <summary>
        /// 底部显示的文字
        /// </summary>
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        /// <summary>
        /// 头部显示的文本值
        /// </summary>
        public string TxtValue
        {
            get { return (string)GetValue(TxtValueProperty); }
            set { SetValue(TxtValueProperty, value); }
        }

        /// <summary>
        /// 显示/隐藏头部数值
        /// </summary>
        public Visibility TopVisible
        {
            get { return (Visibility)GetValue(TopVisibleProperty); }
            set { SetValue(TopVisibleProperty, value); }
        }

        /// <summary>
        /// 显示/隐藏底部文字
        /// </summary>
        public Visibility TextVisible
        {
            get { return (Visibility)GetValue(TextVisibleProperty); }
            set { SetValue(TextVisibleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for TextVisible.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextVisibleProperty =
            DependencyProperty.Register("TextVisible", typeof(Visibility), typeof(HistogramGroup), null);

        // Using a DependencyProperty as the backing store for TopVisible.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TopVisibleProperty =
            DependencyProperty.Register("TopVisible", typeof(Visibility), typeof(HistogramGroup), null);

        // Using a DependencyProperty as the backing store for TxtValue.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TxtValueProperty =
            DependencyProperty.Register("TxtValue", typeof(string), typeof(HistogramGroup), null);

        // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(HistogramGroup), null);

        #endregion

        #region 构造函数
        public HistogramGroup()
        {
            DefaultStyleKey = typeof(HistogramGroup);

            IsShowText = true;
            IsOperable = false;
            TopVisible = Visibility.Collapsed;
        }

        #endregion

        #region 重写OnApplyTemplate方法

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _topGrid = GetTemplateChild("XTopGrid") as Grid;
            _innertPanel = GetTemplateChild("XInnerPanel") as StackPanel;
            _scrollViewer = GetTemplateChild("XScrollViewer") as ScrollViewer;
            _activateHisStoryboard = GetTemplateChild("XActivateHisStoryboard") as Storyboard;

            // 将缓存面板中的控件添加到显示面板中
            if (_innertPanel != null && _cacheStackPanel.Children.Count > 0)
            {
                for (var i = 0; i < _cacheStackPanel.Children.Count; i++)
                {
                    var temp = _cacheStackPanel.Children[i];
                    _cacheStackPanel.Children.RemoveAt(i--);
                    _innertPanel.Children.Add(temp);
                }
            }

            if (_topGrid != null)
                _topGrid.SizeChanged += OntopGrid_SizeChanged;
            if (_innertPanel != null)
                _innertPanel.SizeChanged += OninnertPanel_SizeChanged;
            if (_scrollViewer != null)
                _scrollViewer.SizeChanged += OninnertPanel_SizeChanged;

            if (_activateHisStoryboard != null)
            {
                _animation1 = _activateHisStoryboard.Children[0] as DoubleAnimation;
                _animation2 = _activateHisStoryboard.Children[1] as DoubleAnimation;
            }
        }
        #endregion

        #region 实现IHistogramGroup接口的属性、方法
        /// <summary>
        /// 获取柱状图个数
        /// </summary>
        public int Count
        {
            get
            {
                var panel = _innertPanel ?? _cacheStackPanel;
                return panel.Children.Count;
            }
        }

        /// <summary>
        /// 获取柱状图集合
        /// </summary>
        public List<HistogramControl> Items
        {
            get
            {
                _histogramControlList.Clear();
                var panel = _innertPanel ?? _cacheStackPanel;
                foreach (var navButton in panel.Children.OfType<HistogramControl>())
                {
                    _histogramControlList.Add(navButton);
                }
                return _histogramControlList;
            }
        }

        /// <summary>
        /// 添加柱状图控件
        /// </summary>
        /// <param name="pHistogramCtrl">控件对象</param>
        public void AddItem(HistogramControl pHistogramCtrl)
        {
            if (pHistogramCtrl == null)
                return;

            if (pHistogramCtrl.FactHeight > FactHeight)
                FactHeight = pHistogramCtrl.FactHeight;

            if (pHistogramCtrl.Visibility == Visibility.Visible)
                _displayHistogramList.Add(pHistogramCtrl);

            pHistogramCtrl.HistogramMouseEnter += OnHistogramMouseEnter;
            pHistogramCtrl.HistogramMouseClick += OnHistogramMouseClick;

            // 如果显示面板为null，先添加到缓存面板里，等加载完显示面板再转移其中
            var panel = _innertPanel ?? _cacheStackPanel;
            panel.Children.Add(pHistogramCtrl);
        }

        /// <summary>
        /// 移除柱状图控件
        /// </summary>
        /// <param name="pHistogramCtrl">控件对象</param>
        public void RemoveItem(HistogramControl pHistogramCtrl)
        {
            if (pHistogramCtrl == null || _innertPanel == null)
                return;

            if (_innertPanel.Children.Contains(pHistogramCtrl))
                _innertPanel.Children.Remove(pHistogramCtrl);
        }

        /// <summary>
        /// 移除柱状图控件
        /// </summary>
        /// <param name="pIndex">控件索引</param>
        public void RemoveItem(int pIndex)
        {
            if (_innertPanel == null)
                return;

            if (pIndex > -1 && pIndex < _innertPanel.Children.Count)
                _innertPanel.Children.RemoveAt(pIndex);
        }

        /// <summary>
        /// 清空柱状图控件
        /// </summary>
        public void ClearItems()
        {
            if (_innertPanel != null)
            {
                _innertPanel.Children.Clear();
                _displayHistogramList.Clear();
                _histogramControlList.Clear();
            }
        }

        /// <summary>
        /// 显示/隐藏指定柱状图
        /// </summary>
        /// <param name="pIndex">元素索引</param>
        /// <param name="pIsShow">true表示显示；false表示隐藏</param>
        public void ShowHideItem(int pIndex, bool pIsShow)
        {
            List<HistogramControl> list = Items;
            for (int i = 0; i < Count; i++)
            {
                if (pIndex == i)
                {
                    if (pIsShow)
                    {
                        if (!_displayHistogramList.Contains(list[i]))
                        {
                            int index = 0;
                            for (int j = 0; j < _displayHistogramList.Count; j++)
                            {
                                if (pIndex < _displayHistogramList[j].Index)
                                    break;
                                ++index;
                            }
                            _displayHistogramList.Insert(index, list[i]);
                        }
                        list[i].Visibility = Visibility.Visible;
                    }
                    else
                    {
                        if (_displayHistogramList.Contains(list[i]))
                            _displayHistogramList.Remove(list[i]);
                        list[i].Visibility = Visibility.Collapsed;
                    }
                    break;
                }
            }
        }
        #endregion

        #region 事件
        /// <summary>
        /// ScrollViewer、StackPanel改变大小时触发事件
        /// 重新设置柱状图的MarginLeft值
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OninnertPanel_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            for (var i = 1; i < _innertPanel.Children.Count; i++)
            {
                var histogram = _innertPanel.Children[i] as HistogramControl;
                if (histogram == null)
                    continue;

                var marginLeft = histogram.ActualWidth > 8.0 ? 8.0 : histogram.ActualWidth;
                histogram.Margin = new Thickness(marginLeft, 0, 0, 0);
            }
        }

        /// <summary>
        /// 获取TopGrid的实际大小
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OntopGrid_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            _topGridWidth = _topGrid.ActualWidth;
            _topGridHeight = _topGrid.ActualHeight;

            BeginStoryboard();
        }

        /// <summary>
        /// 执行动画
        /// </summary>
        private void BeginStoryboard()
        {
            if (_animation1 == null || _animation2 == null)
                return;

            GeneralTransform generalTrans = ActivateHistogram.CenterRect.TransformToVisual(this);
            Point pt = generalTrans.Transform(new Point(0, 0));
            _animation1.To = pt.X - (_topGridWidth - HistogramControl.NarrowWidth + 1) / 2;
            _animation2.To = pt.Y - _topGridHeight;
            _activateHisStoryboard.Begin();
        }

        /// <summary>
        /// 鼠标移入柱状图控件时触发
        /// </summary>
        /// <param name="pHistogramCtrl"></param>
        private void OnHistogramMouseEnter(HistogramControl pHistogramCtrl)
        {
            if (TopVisible == Visibility.Collapsed)
                TopVisible = Visibility.Visible;

            if (ActivateHistogram != null)
            {
                if (ActivateHistogram == pHistogramCtrl)
                    return;
                if (ActivateHistogram != CheckedHistogram)
                    ActivateHistogram.ResetRectState();
            }

            ActivateHistogram = pHistogramCtrl;
            TxtValue = ActivateHistogram.TxtValue;

            BeginStoryboard();
        }

        /// <summary>
        /// 鼠标点击柱状图控件时触发
        /// </summary>
        /// <param name="pHistogramCtrl"></param>
        private void OnHistogramMouseClick(HistogramControl pHistogramCtrl)
        {
            if (CheckedHistogram != null)
            {
                if (CheckedHistogram == pHistogramCtrl)
                    return;
                CheckedHistogram.ResetRectState();
            }

            CheckedHistogram = pHistogramCtrl;
        }
        #endregion
    }
}
